/*
 *  jQuery to power the fancy slide module.
 *
 */
 
(function($) {
  $.fn.fancySlide = function(options){  
    var defaultoptions = {
      animation:      'slide', // Transition style
      continuous:     true,    // Return to first slide when last slide is
                               // reached
      controlsBefore: '',      // Prefix slide description
      controlsAfter:  '',      // Suffix slide description
      controlsType:   'thumbs',// Choose whether to use left right buttons or thumbs
      showControls:   true,    // Add controller to the slider
      slideControls:  false,   // Makes controls slide up and down on mouseover
      vertical:       false,   // Slide animations move vertically
      speed:          800,     // Transition time
      rotate:         true,    // Let slider animate by itself
      pause:          4000     // Pause time between transitions
    };

    var options = $.extend(defaultoptions, options);
    var obj = $(this);
    var slidewidth = $(this).outerWidth();
    var slideheight = $(this).outerHeight();
    var slides = $('li', obj).length;
    var currentslide = 0;
    var previousslide = 0;
    var position = 0;
    var timeout;
    var depth = 99;
    // Append to animation function name
    var animationtype = options.animation + 'animate';
   
    if (options.speed == 0) {
      animationtype = 'dontanimate';
    }
    
    /*
     *  Initiate the fancy slider.
     *
     */
    return this.each(function() {

      obj.width(slidewidth);
      obj.height(slideheight);
      obj.css('overflow', 'hidden');
      
      if(options.showControls) {
        if(options.controlsType == 'thumbs') {
          var html = '<div class="controller">';
          html += '<span>' + options.controlsBefore + '</span>';
          for (i = 0; i < slides; i++){
            var thistitle = $('li img:eq(' + i + ')', obj);
            html += '<p>' + thistitle.attr('alt') + '</p>';
          }
          html += '<div class="controls">';
          for (i = 0; i < slides; i++){
            var thisslide = $('li img:eq(' + i + ')', obj);
            html += '<a href="#" title ="' + thisslide.attr('alt') + '">'
            html += '<img src="' + thisslide.attr('src') + '" alt="' + thisslide.attr('alt') + '" />'
            html += '</a>';
          }
          html += '</div>';
          html += '</div>';
          html += options.controlsAfter;            
          $(obj).append(html);
      
         controller = $('.controller', obj);
         $(controller).css('zIndex', depth + 1);
         $(controller).css('width', slidewidth - 20);
          
          // Make sure controller link images are sized correctly
          $('img', controller).attr('height', '40');     
  
          // Set classes for controller text and buttons
          showinfo();
  
          // Add sliding animation for controller
          if (options.slideControls) {
          var controlsheight = $(controller).outerHeight();
          $(controller).css('bottom','-' + controlsheight + 'px');
          obj.hover(
            function() {
                $(controller).stop().animate({bottom:'0px'}, 300);
              }, 
              function() {
                $(controller).stop().animate({bottom:'-' + controlsheight + 'px'}, 300);
              }
            );
          }
          
          // Give controller links functionality to change slides
          $('a', controller).each(function(i) {
            $(this).bind('click', function() {
                previousslide = currentslide;
                currentslide = i;
                if (animationtype == 'dwipe') {
                  $('li #effect .effect1:animated, li #effect .effect2:animated').stop();
                  $('li:not(' + currentslide + ')', obj).css('display', 'none');
                  $('li:eq(' + currentslide + ')', obj).css('display', 'block');
                  $('li #effect', obj).remove();
                  eval(animationtype + '(' + currentslide + ',' + previousslide + ',' + true + ')');
                } else {
                  eval(animationtype + '(' + currentslide + ',' + previousslide + ',' + true + ')');
                }
                return false;
              });
          });
        };      
      } else if(options.controlsType == 'buttons') {
        var html = '<span id="back">';
        html += '<a href="#">Back</a>';
        html += '</span>';
        html += '<span id="forward">';
        html += '<a href="#">Forward</a>';
        html += '</span>';
        $(obj).append(html);
      };
      
      // Set slider CSS to override default drupal
      if (animationtype == 'slideanimate') {
        $('ul', obj).css({
          'margin' : 0,
          'padding' : 0,
          'width': slides*slidewidth
          });    
        $('li', obj).css({
          'float' : (options.vertical ? 'none' : 'left'),
          'height' : slideheight,
          'width' : slidewidth
        });
      } else {
        $('ul', obj).css({
          'height' : slideheight,
          'width' : slidewidth
        });
        $('li', obj).css({
          'height' : slideheight,
          'left' : '0',
          'position' : 'absolute',
          'top' : '0',
          'width' : slidewidth
        });
                  
        for (i = 0; i < slides; i++){
          $('li:eq(' + i + ')', obj).css('zIndex', depth);
          depth--;
        }
      }
      
      if (options.rotate) {
        timeout = setTimeout(function(){
          eval(animationtype + '("rotate",' + previousslide + ',' + false + ')');
          },options.pause);
      };
    });
    
    // Work out which slide to animate to
    function animationmechanic(destination) {
      if (destination == 'rotate') {
        currentslide++;
        if (currentslide > slides - 1) {
          currentslide = options.continuous ? 0 : currentslide - 1;
        }
      } else {      
        currentslide = destination;
      };
      
      return currentslide;
      
    };
    
    /*
     *  Don't animate transition. If speed is set to 0 use this to save on overhead
     *
     */
    function dontanimate(destination, current, clicked) {
      
      if (destination == current){ //prevent button clicks on current slide
        if(clicked) {clearTimeout(timeout)}; //reset timeout if controller links are clicked
        return;
      }
      
      animationmechanic(destination);
      
      if (options.showControls) {
        showinfo();
      };
      var theslide = currentslide;
      var diff = (currentslide - theslide + slides) % slides;
      var speed = diff * options.speed;
      
      if (!clicked){
        if (currentslide == 0){
          previousslide = slides - 1;
        } else {
          previousslide = currentslide - 1;
        }
      }
           
      $('li:eq(' + previousslide + ')', obj).stop(true, true).hide();
      $('li:eq(' + currentslide + ')', obj).stop(true, true).show();
     
      if(clicked) clearTimeout(timeout); // Reset timeout if controller links are clicked
      
      if(options.rotate) {
        timeout = setTimeout(function(){
          eval(animationtype + '("rotate",' + previousslide + ',' + false + ')');
        }, diff*speed + options.pause);
      }; 
    };
       
    /*
     *  Slide transition
     *
     */
    function slideanimate(destination, current, clicked) {
      
      if (destination == current){ //prevent button clicks on current slide
        if(clicked) {clearTimeout(timeout)}; //reset timeout if controller links are clicked
        return;
      }
      
      animationmechanic(destination);
      
      if (options.showControls) {
        showinfo();
      };
      var theslide = currentslide;
      var diff = Math.abs(theslide-currentslide);
      var speed = diff * options.speed;
      
      if (!options.vertical) {
        position = (currentslide * slidewidth * -1);
        $('ul', obj).stop().animate({marginLeft: position}, speed);
      } else {
        position = (currentslide * slideheight * -1);
        $('ul', obj).stop().animate({marginTop: position}, speed);
      };

      if (clicked) clearTimeout(timeout); // Reset timeout if controller links are clicked
    
      if (options.rotate) {
        timeout = setTimeout(function(){
          eval(animationtype + '("rotate",' + previousslide + ',' + false + ')');
        }, diff*speed + options.pause);
      };
      
    };
    
    /*
     *  Fade transition
     *
     */
    function fadeanimate(destination, current, clicked) {
      
      if (destination == current){ //prevent button clicks on current slide
        if(clicked) {clearTimeout(timeout)}; //reset timeout if controller links are clicked
        return;
      }
      
      animationmechanic(destination);
      
      if (options.showControls) {
        showinfo();
      };

      if (!clicked){
        if (currentslide == 0){
          previousslide = slides - 1;
        } else {
          previousslide = currentslide - 1;
        }
      }
      var theslide = currentslide;
      var diff = Math.abs(theslide - currentslide);
      var speed = diff * options.speed;
      
      $('li:eq(' + previousslide + ')', obj).stop(true, true).fadeOut(speed);
      $('li:eq(' + currentslide + ')', obj).stop(true, true).fadeIn(speed);
     
      if(clicked) clearTimeout(timeout); // Reset timeout if controller links are clicked
      
      if(options.rotate) {
        timeout = setTimeout(function(){
          eval(animationtype + '("rotate",' + previousslide + ',' + false + ')');
        }, diff*speed + options.pause);
      }; 
    };
    
    /*
     *  Doublewipe transition
     *
     */
    function dwipeanimate(destination, current, clicked) {
      
      if (destination == current){ //prevent button clicks on current slide
        if(clicked) {clearTimeout(timeout)}; //reset timeout if controller links are clicked
        return;
      }
      
      animationmechanic(destination);
      
      if (options.showControls) {
        showinfo();
      };

      if (!clicked){
        if (currentslide == 0){
          previousslide = slides - 1;
        } else {
          previousslide = currentslide - 1;
        }
      }
      
      //The previous slide - add 2 divs on this with the currentslide img as a background.
      //Then animate them closing. Then remove and hide the li to reveal the next.

      var effectimg = $('li:eq(' + currentslide + ') img' , obj).attr('src');  
      var effecthtml = '<div id="effect">';
      effecthtml +='<div class="effect1">';
      effecthtml += '</div>';      
      effecthtml += '<div class="effect2">';
      effecthtml += '</div>';
      effecthtml += '</div>';
      
      $('li:eq(' + previousslide + ')', obj).prepend(effecthtml);

      // Add the css for the effect
      $('li:eq(' + previousslide + ') #effect', obj).css({
        'height' : slideheight,
        'left' : 0,
        'overflow' : 'hidden',
        'position' : 'absolute',
        'top' : 0,
        'width' : slidewidth
      });
            
      $('li:eq(' + previousslide + ') #effect .effect1', obj).css({
        'background' : 'url(' + effectimg + ') no-repeat ' + '0 ' + '0',
        'display' : 'block',
        'height' : slideheight / 2,
        'left' : '0',
        'position' : 'relative',
        'top' : -slideheight / 2,
        'width' : slidewidth
      });
      $('li:eq(' + previousslide + ') #effect .effect2', obj).css({
        'background' : 'url(' + effectimg + ') no-repeat ' + '0 ' + -slideheight / 2 + 'px',
        'display' : 'block',
        'height' : slideheight / 2,
        'left' : '0',
        'position' : 'relative',
        'top' : slideheight,
        'width' : slidewidth
      });
      
      var theslide = currentslide;
      var diff = Math.abs(theslide - currentslide);
      var speed = diff * options.speed;

      $('li:eq(' + previousslide + ') #effect .effect1', obj).stop(true, true).animate({'top':0,'left':0}, speed);
      $('li:eq(' + previousslide + ') #effect .effect2', obj).stop(true, true).animate({'top':0,'left':0}, speed, function() {
        $('li:not(' + currentslide + ')', obj).css('display', 'none');
        $('li:eq(' + currentslide + ')', obj).css('display', 'block');
        $('li #effect', obj).remove();
      });
      
      if(clicked) clearTimeout(timeout); // Reset timeout if controller links are clicked
      
      if(options.rotate) {
        timeout = setTimeout(function(){
          eval(animationtype + '("rotate",' + previousslide + ',' + false + ')');
        }, diff*speed + options.pause);
      }; 
    };
    
    // Change classes on controller info and button states 
    function showinfo() {
      controller = $('.controller', obj);
      $('p', controller).addClass('inactive');
      $('a', controller).addClass('inactive');
      $('p.active', controller).removeClass('active');
      $('a.active', controller).removeClass('active');
      $('p:eq(' + currentslide + ')', controller).removeClass('inactive');
      $('p:eq(' + currentslide + ')', controller).addClass('active');
      $('a:eq(' + currentslide + ')', controller).removeClass('inactive');
      $('a:eq(' + currentslide + ')', controller).addClass('active');
    };
  };
  
})(jQuery);
